package com.yuncheng.spcyApi.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.collections.CollectionUtils;
import utils.DateConversionUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Field;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.*;

public class MapUtils {
    //java对象转map
    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(obj));
        }
        return map;
    }

    /**
     *  将List<Map> 数据，去空，并将日期转换
     */
    public static List<Map<String,Object>> listMapKeyByDelEmpty(List<Map<String,Object>> mapList){
        List<Map<String,Object>> newMapList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(mapList)) {
            for (Map<String, Object> map : mapList) {
                map = MapUtils.keyToLowerCase(map);
                newMapList.add(map);
            }
        }
        return newMapList;
    }

    /**
     * map类型的数据key转换为小写
     * @param orgMap
     * @return
     */
    public static Map<String, Object> keyToLowerCase(Map<String, Object> orgMap) {
        Map<String, Object> resultMap = new HashMap<>();

        if (orgMap == null || orgMap.isEmpty()) {
            return resultMap;
        }
        Set<Map.Entry<String,Object>> entrySet = orgMap.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            String key = entry.getKey();
            Object value = entry.getValue();

            /*if (value != null) {
                boolean timestamp = this.isTimestamp(value.toString());

                if (timestamp) {
                    String date = this.timestampToDate(Long.parseLong(value.toString()));
                    resultMap.put(key.toLowerCase(), date);
                } else {
                    resultMap.put(key.toLowerCase(), value);
                }
            }else {
                resultMap.put(key.toLowerCase(), value);
            }*/

            // 时间戳
            if (value instanceof Date){
                if (value != null) {
//                    String date = this.timestampToDate();
//                    Date date = new Date(String.valueOf(value));
                    String date = DateConversionUtils.DateToDays((Date) value);
                    resultMap.put(key.toLowerCase(), date);
                }else {
                    resultMap.put(key.toLowerCase(), value);
                }
                // 转日期
                /*if (value != null && ((int[]) value).length == 13){
                    System.out.println(((Long) value).longValue());
                    String date = this.timestampToDate(((Long) value).longValue());
                    resultMap.put(key.toLowerCase(), date);
                }else {
                    resultMap.put(key.toLowerCase(), value);
                }*/
            }else {
                resultMap.put(key.toLowerCase(), value);
            }
        }
        return resultMap;
    }

    /**
     * map类型的数据key转换为小写(并将Clob字段转为String)
     * @param orgMap
     * @return
     */
    public static Map<String, Object> keyToLowerCaseAndString(Map<String, Object> orgMap) throws IOException, SQLException {
        Map<String, Object> resultMap = new HashMap<>();

        if (orgMap == null || orgMap.isEmpty()) {
            return resultMap;
        }
        Set<Map.Entry<String,Object>> entrySet = orgMap.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            String key = entry.getKey();
            Object value = entry.getValue();

            // 时间戳
            if (value instanceof Date){
                if (value != null) {
                    String date = DateConversionUtils.DateToDays((Date) value);
                    resultMap.put(key.toLowerCase(), date);
                }else {
                    resultMap.put(key.toLowerCase(), value);
                }
            }else if (value instanceof Clob){
                String clobToString = ClobToString((Clob) value);
                resultMap.put(key.toLowerCase(), clobToString);
            }
            else {
                resultMap.put(key.toLowerCase(), value);
            }
        }
        return resultMap;
    }

    /**
     * 将 List<Map>转为 json对象，并保留空值属性
     * @param newMapList
     * @return
     */
    public static JSONArray listMapToJson(List<Map<String,Object>> newMapList){
        List<Map<String, Object>> mapList = MapUtils.listMapKeyByDelEmpty(newMapList);

        // 将List<Map>转为 json字符串，保留空值key
        String s = JSON.toJSONString(mapList, new SerializeFilter[]{}, SerializerFeature.WriteMapNullValue);
        JSONArray objects = JSONObject.parseArray(s);

        return objects;
    }

    /**
     * 将Map转为 jsonObject对象
     * @param newMap
     * @return
     */
    public static JSONObject mapToObject(Map<String,Object> newMap){
        JSONObject jsonObject = new JSONObject();
        if (newMap == null || newMap.isEmpty()) {
            return jsonObject;
        }
        newMap = MapUtils.keyToLowerCase(newMap);
        Set<Map.Entry<String,Object>> entrySet = newMap.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            String key = entry.getKey();
            Object value = entry.getValue();
            jsonObject.put(key,value);
        }
        return jsonObject;
    }

    /**
     * 将Clob转 string（大文本转字符串）
     * @param clob
     * @return
     * @throws SQLException
     * @throws IOException
     */
    public static String ClobToString(Clob clob) throws SQLException, IOException {
        String ret = "";
        Reader read= clob.getCharacterStream();
        BufferedReader br = new BufferedReader(read);
        String s = br.readLine();
        StringBuffer sb = new StringBuffer();
        while (s != null) {
            sb.append(s);
            s = br.readLine();
        }
        ret = sb.toString();
        if(br != null){
            br.close();
        }
        if(read != null){
            read.close();
        }
        return ret;
    }
}
